/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package DB;

import javax.persistence.*;
import POJOS.*;

import java.util.Collection;
import java.util.List;
import javax.swing.JOptionPane;


/**
 *
 * @author jim
 */
public class DBmanager {
    private static EntityManagerFactory emf;
    private static EntityManager em;
    
    //Σύνδεση με τη βάση δεδομένων
    public static void openConnection() {
        try {
         /* Δημιουργία EntityManagerFactory για το Persistence Unit της ΒΔ μας */
            emf = Persistence.createEntityManagerFactory("RadioStationPU"); 
    /* Δημιουργία EntityManager */
            em = emf.createEntityManager(); 
        } catch(Exception e) {
            
            System.out.println(e); 
            JOptionPane.showMessageDialog(null, "Αποτυχία σύνδεσης με τη ΒΔ!", "ERROR", JOptionPane.ERROR_MESSAGE);
        }
    }

    public static void closeConnection() {
        try {
    /* Κλείσιμο EntityManager */
            em.close();
    /* Κλείσιμο EntityManagerFactory */
            emf.close();
        } catch(Exception e){ 
            System.out.println(e);
            JOptionPane.showMessageDialog(null, "Αποσύνδεση από τη ΒΔ!", "ERROR", JOptionPane.ERROR_MESSAGE);
        }
    }

    public EntityManager getEm() {
        return em;
    }
 
    //Επιστρέφει όλους τους καλλιτέχνες
    public static List getallartist() {
        javax.persistence.Query artistquery;
        List artists;
        artistquery =  em.createQuery("SELECT a FROM Artist a");
        artists=   artistquery.getResultList();
        return artists;
    }

    //Αποθηκεύει τον καλλιτέχνη στη βάση
    public static boolean SaveArtist (Artist artist){
        try{
         em.getTransaction().begin();
         em.persist(artist);
         em.getTransaction().commit();
        }catch(Exception e){
            System.out.println(e);
            return false;
        }
        return true;
    }
    
    //Αποθηκεύει τον καλλιτέχνη στη βάση, στην τροποποίηση
    public static boolean ModifyArtist(Artist artist){
    try{
        em.getTransaction().begin();
         
        em.merge(artist);
        em.getTransaction().commit();
        return true;
    }catch(Exception e){
        System.out.println(e);
        return false;
        }
    }
    
    //Διαγράφει τον καλλιτέχνη
    public static boolean DeleteArtist(Artist artist){
    try{
        em.getTransaction().begin();
         
        Artist a = em.merge(artist);
        em.remove(a);
        em.getTransaction().commit();
        return true;
    } catch (Exception e){
        System.out.println(e);
        return false;
        }
    }
    
    //Αφαιρεί από τον καλλιτέχνη το άλμπουμ
    public static boolean DeleteArtistAlbum(Album album,Artist artist){
    try{
        em.getTransaction().begin();
         
        Artist a = em.merge(artist);
        a.getAlbumCollection().remove(album);
        em.getTransaction().commit();
        return true;
    } catch (Exception e){
        System.out.println(e);
        return false;
        }
    }
    
    //Προσθέτει το άλμπουμ στον καλλιτέχνη
    public static boolean SaveArtistAlbum(Album album,Artist artist){
    try{
        em.getTransaction().begin();
         
        Artist a = em.merge(artist);
        a.getAlbumCollection().add(album);
        em.getTransaction().commit();
        return true;
    } catch (Exception e){
        System.out.println(e);
        return false;
        }
    }
    
    
    
    //Επιστρέφει όλα τα συγκροτήματα
    public static List getallMusicGroup() {
        javax.persistence.Query musicGroupquery;
        List musicGroups;
        musicGroupquery =  em.createQuery("SELECT m FROM MusicGroup m");
        musicGroups=   musicGroupquery.getResultList();
        return musicGroups;
    }
    
    //Αποθηκεύει ένα νέο συγκρότημα
    public static boolean SaveMusicGroup(MusicGroup musicGroup) {
        try{
            em.getTransaction().begin();
            em.persist(musicGroup);
            em.getTransaction().commit();
        }catch(Exception e){
            System.out.println(e);
            return false;
        }
        return true;
    }
    
    //Αποθηκεύει ένα νέο συγκρότημα, στην τροποποίηση
     public static boolean ModifyMusicGroup(MusicGroup musicGroup) {
        try{
            em.getTransaction().begin();
         
            em.merge(musicGroup);
            em.getTransaction().commit();
            return true;
        }catch(Exception e){
            System.out.println(e);
            return false;
        }
    }
    
     //Διαγράφει ένα συγκρότημα
    public static boolean DeleteMusicGroup(MusicGroup musicGroup){
    try{
        em.getTransaction().begin();
        MusicGroup m = em.merge(musicGroup);
        em.remove(m); 
        em.getTransaction().commit();
        return true;
        } catch (Exception e){
            System.out.println(e);
            return false;
        }
    }
    
    //Αφαιρεί από το συγκρότημα τον καλλιτέχνη
    public static boolean deleteArtistAndMusicGroup (MusicGroup musicGroup,Collection<Artist> artistList ){
        try{
            em.getTransaction().begin();
            
            for(Artist artist : musicGroup.getArtistCollection()){
                artist= em.merge(artist);
                artist.getMusicGroupCollection().remove(musicGroup);
            }
            musicGroup.getArtistCollection().retainAll(artistList);
            
            em.getTransaction().commit();
            return true;     
            } catch (Exception e) {
            System.out.println(e);
            return false;
        }
    }
    
    //Αποθηκεύει/διαγράφει στο συγκρότημα καλλιτέχνες
    public static boolean SaveArtistAndMusicGroup (MusicGroup musicGroup,List<Artist> artistList ){
        try{
            em.getTransaction().begin();
            
            for(Artist artist : musicGroup.getArtistCollection()){
                artist= em.merge(artist);
                if(!artistList.contains(artist)){
                     //musicGroup.getArtistCollection().remove(artist);
                    artist.getMusicGroupCollection().remove(musicGroup);
                }
            }
            musicGroup.getArtistCollection().retainAll(artistList);
            
            for (Artist artist: artistList){
                artist= em.merge(artist);
                if(!musicGroup.getArtistCollection().contains(artist)){
                    musicGroup.getArtistCollection().add(artist);
                    artist.getMusicGroupCollection().add(musicGroup);
                }
            }
            
            em.getTransaction().commit();
            return true;     
            } catch (Exception e) {
            System.out.println(e);
            return false;
        }
    }
    
    
    
    //Αποθηκεύει το άλμπουμ, στην τροποποίηση
    public static boolean ModifyAlbum(Album album) {
         try{
            em.getTransaction().begin();
            em.merge(album);
            em.getTransaction().commit();
            return true;
        }catch(Exception e){
            System.out.println(e);
            return false;
        }
    }

    //Διαγράφει το άλμπουμ
    public static boolean DeleteAlbum(Album album) {
        try{
        em.getTransaction().begin();
         
        Album al = em.merge(album);
        em.remove(al);
        em.getTransaction().commit();
        return true;
    } catch (Exception e){
        System.out.println(e);
        return false;
        }
    }
      
    //Αφαιρεί από το συγκρότημα το άλμπουμ
    public static boolean DeleteAlbumMusicGroup(Album album, MusicGroup musicGroup) {
        try{
        em.getTransaction().begin();
         
        MusicGroup mg = em.merge(musicGroup);
        mg.getAlbumCollection().remove(album);
        
        em.getTransaction().commit();
        return true;
    } catch (Exception e){
        System.out.println(e);
        return false;
        }
    }
    
    //Αποθηκεύει το άλμπουμ
    public static boolean SaveAlbum(Album album) {
        try{
            em.getTransaction().begin();
            em.persist(album);
            em.getTransaction().commit();
        }catch(Exception e){
            System.out.println(e);
            return false;
        }
        return true;
    }
    
    //Προσθέτει το άλμπουμ στο συγκρότημα
     public static boolean SaveAlbumMusicGroup(Album album, MusicGroup musicGroup) {
        try{
        em.getTransaction().begin();
         
        MusicGroup mg = em.merge(musicGroup);
        mg.getAlbumCollection().add(album);
        em.getTransaction().commit();
        return true;
    } catch (Exception e){
        System.out.println(e);
        return false;
        }
    }
    
     
     //Αποθηκεύει ένα νέο τραγούδι
    public static boolean SaveSong(Album album,Song song) {
       try{
       em.getTransaction().begin();
          song = em.merge(song);
          album.getSongCollection().add(song);
          em.getTransaction().commit();
   }catch(Exception e){
       System.out.println(e);
       return false;
   }
    return true;
    }
    
    //Αποθηκεύει το τραγούδι στο άλμπουμ
    public static boolean addToSongCollection(Album album,Song song) {
       try{
       em.getTransaction().begin();
       
        if(!album.getSongCollection().contains(song)){
          Song s= em.merge(song);
          album.getSongCollection().add(s);
        }
        em.getTransaction().commit();
          
    }catch(Exception e){
       System.out.println(e);
       return false;
    }
    return true;
    }
    
    //Διαγράφει το τραγούδι από το άλμπουμ
   public static boolean deleteFromSongCollection(Album album,List<Song> songList) {
        try{
            em.getTransaction().begin();
            for(Song song: album.getSongCollection()){
                Song s= em.merge(song);
                if(!songList.contains(s)){
              //album.getSongCollection().remove(s);
                    em.remove(s);
                }
            }
            album.getSongCollection().retainAll(songList);
            em.getTransaction().commit();
        }catch(Exception e){
            System.out.println(e);
            return false;
        }    
        return true;
    }
      
    
   
   //Επιστρέφει το Id_musicGenre από το Name_MusicGenre
    public static MusicGenre identifyMusicGenrewithNameMusicGenre(String Name_MusicGenre){
        MusicGenre Id_musicGenre;
     
        Query findWithName = em.createNamedQuery("MusicGenre.findByNameMusicGenre",MusicGenre.class);
     
        try{
            findWithName.setParameter("nameMusicGenre", Name_MusicGenre);
            Id_musicGenre = (MusicGenre) findWithName.getSingleResult();
        }catch(Exception e){
            return null;
        }
        return Id_musicGenre;
    }
                  
    //Ειστρέφει Id_Mpc από το Name_Mpc
    public static MusicProductionCompany identifyMusicCompanywithNameMusicCompany(String Name_Mpc){
        MusicProductionCompany Id_Mpc;
     
        Query findWithName = em.createNamedQuery("MusicProductionCompany.findByNameMpc",MusicProductionCompany.class);
     
        try{
            findWithName.setParameter("nameMpc", Name_Mpc);
            Id_Mpc = (MusicProductionCompany) findWithName.getSingleResult();
        }catch(Exception e){
        return null;
        }
        return Id_Mpc;
    }
 
    //Επιστρέφει το Id_musicGroup από το Name_MusicGroup
    public static MusicGroup identifyMusicGroupwithNameMusicGroup(String Name_MusicGroup){
        MusicGroup Id_musicGroup;
     
        Query findWithName = em.createNamedQuery("MusicGroup.findByNameMusicGroup",MusicGroup.class);
     
        try{
            findWithName.setParameter("nameMusicGroup", Name_MusicGroup);
            Id_musicGroup = (MusicGroup) findWithName.getSingleResult();
        }catch(Exception e){
            return null;
        }
        return Id_musicGroup;
    }
 
    //Επιστρέφει το Id_Artist από το Artistic_Artist
    public static Artist identifyArtistwithArtisticName(String Artistic_Artist) {
        Artist Id_Artist;
        
        Query findWithName= em.createNamedQuery("Artist.findByArtisticName",Artist.class);
        try{
            findWithName.setParameter("artisticName", Artistic_Artist);
            Id_Artist = (Artist) findWithName.getSingleResult();
        }catch(Exception e){
            return null;
        }
        return Id_Artist;
    }
}





